package com.hezhou.oauth2.resource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;

/**
 * ---------------------------
 * (ResourceServerConfig) 资源服务器配置
 * @EnableResourceServer 声明是个资源服务器
 * ---------------------------
 *
 * @Author: [hezhou]
 * @Date: 2020/3/13
 * @Version: [1.0.1]
 * ---------------------------
 */
@Configuration
@EnableResourceServer //标识为资源服务器以后请求服务器的资源  就要带上token ，找不到或者token无效访问不了资源
@EnableGlobalMethodSecurity(prePostEnabled = true)  //开启方法级别的权限控制
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    public static final String RESOURCE_PRODUCT_SERVER = "product-server";

    /**
     * 远程认证服务器进行检验 检验token是否有效
     * 令牌端点的安全配置
     * @return
     */
    @Bean
    public ResourceServerTokenServices tokenService(){
        RemoteTokenServices remoteTokenServices = new RemoteTokenServices();
        //请求认证服务器的地址  默认是关闭的  要设置为认证通过可访问
        //这个一定要配准  不然就会报500  找不到body
        remoteTokenServices.setCheckTokenEndpointUrl("http://localhost:8090/auth/oauth/check_token");
        remoteTokenServices.setClientId("hezhou-pc");
        remoteTokenServices.setClientSecret("mengxuegu-secret");
        return remoteTokenServices;
    }

    /**
     * 设置资源链  资源配置
     * @param resources
     * @throws Exception
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        //当前资源服务器的id  会认证有没有访问这个资源的权限
        resources.resourceId(RESOURCE_PRODUCT_SERVER)
                //设置他的token 远程认证服务器
        .tokenServices(tokenService());
        ;
    }

    /**
     * 配置资源安全过滤器链
     * @param http
     * @throws Exception
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.sessionManagement()
                //springSecurity不会使用也不会创建httpSession实例
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().authorizeRequests()
                .antMatchers("/product/list").hasAuthority("product:list")
                .anyRequest().access("#oauth2.hasScope('all')");
                //等价于上面
//              .antMatchers("/product/**").access("#oauth2.hasScope('all')");  //所有的请求都需要有all范围
    }
}
